package mqtt

import (
	"crypto/tls"
	"errors"
	"gitee.com/injoyai/goutil/conv"
	mqtt "github.com/eclipse/paho.mqtt.golang"
	"log"
)

// NewClient 新建新Mqtt连接 支持原生和阿里云
func NewClient(op *Option) *Client {
	return newMQTT(op)
}

type Client struct {
	option *Option
	client mqtt.Client
	err    error
}

func (this *Client) Cfg() *Option {
	return this.option
}

func (this *Client) Err() error {
	return this.err
}

func (this *Client) Debug(b ...bool) {
	this.option.Debug = !(len(b) > 0 && !b[0])
}

func (this *Client) Close() error {
	this.client.Disconnect(0)
	return nil
}

// Send 发布数据,如果是阿里云则需要加上前缀,自行拼接 "xxx/p2p/xxx@@@"+"xxx"
func (this *Client) Send(target string, msg []byte) (err error) {
	//打印数据,保存记录
	defer func() {
		if this.option.Debug {
			log.Println("[发送]", string(msg), " 到 ", target, conv.New(err).String("成功"))
		}
	}()
	token := this.client.Publish(target, this.option.Qos, this.option.Retained, msg)
	if !token.WaitTimeout(this.option.Timeout) {
		return errors.New("发送超时")
	}
	if token.Error() != nil {
		return token.Error()
	}
	return nil
}

func newMQTT(option *Option) *Client {
	client := &Client{option: option}
	var tls *tls.Config
	if option.TLS {
		tls, client.err = option.TLSOption.New()
		if client.err != nil {
			return client
		}
	}
	client.client = mqtt.NewClient(
		mqtt.NewClientOptions().
			SetTLSConfig(tls).
			AddBroker(option.BrokerURL).
			SetClientID(option.ClientID).
			SetUsername(option.Username).
			SetPassword(option.Password).
			SetDefaultPublishHandler(option.handler).
			SetConnectTimeout(option.Timeout).
			SetKeepAlive(option.KeepAlive).
			SetAutoReconnect(true). //自动重连
			SetCleanSession(false)) //重连后恢复session
	token := client.client.Connect()
	token.Wait()
	log.Printf("MQTT(%s)连接 %s\n", option.ClientID, conv.New(token.Error()).String("成功"))
	client.err = token.Error()
	return client
}

type Write struct {
	Target  string // 目标topic
	*Client        //客户端
}

func (this *Write) Write(p []byte) (int, error) {
	err := this.Send(this.Target, p)
	return len(p), err
}
